
#ifndef SX_SCENE_CONTROLLER_H
#define SX_SCENE_CONTROLLER_H

#include <sxViewController.h>
#include <sxPickingController.h>

/* Controller delegate interface used for picking. */
using Sx::Graphics::Picking::PickingController;

namespace Sx {
namespace Interface {

/* 
 * Abstract canvas type for drawing on the view presented by the scene
 * controller class.
 */
class Canvas;

/* 
 * The scene picking controller depends on the type of camera that is used
 * to implement the view. The type of camera is defined by the ViewController
 * class.
 */
typedef PickingController<Camera_Archetype::ObjectType> ScenePickingController;

/*
 * The scene abstract controller contains the skeletal definition required to
 * interact with objects in a scene. Controllers derived from the
 * SceneController class can override the existing functions to allow the user
 * to interact with the objects specific to the new controller type.
 */
class SceneController : public ViewController {
public:
	SceneController(Viewport* viewport, const std::shared_ptr<Canvas>& canvas, const std::shared_ptr<ScenePickingController>& pickingController, const std::shared_ptr<RendererImplementation>& cameraRenderer);
	virtual ~SceneController();

	virtual bool initialize();

	virtual bool preRender() const;
	virtual void render() const;
	virtual bool postRender() const;

	bool project(const Eigen::Vector3f& worldPoint, Eigen::Vector2i& viewPoint);
	bool unproject(int x, int y, Eigen::Vector3f& origin, Eigen::Vector3f& direction);
	bool createPickRay(int x, int y, Eigen::Vector3f& start, Eigen::Vector3f& end);

protected:
	/*
	 * The canvas interface allows for controllers to manage customized drawing.
	 */
	std::shared_ptr<Canvas> canvas;

	/*
	 * The picking controller provides an interface to project and unproject
	 * points from 2D space to 3D space. Derived classes can use this for 
	 * implementing selection and user-world interaction schemes.
	 */
	std::shared_ptr<ScenePickingController> pickingController;
};

}

}

#endif
